﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using NewRetail.Application.Components.WeChat.Services;
using NewRetail.Application.Core;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using Microsoft.Extensions.Logging;
using NewRetail.Application.Components.WeChat.Model;
using System;

namespace NewRetail.Api.Controllers.WeChatControllers
{
    /// <summary>
    /// 用于处理微信回调的信息
    /// </summary>
    [NewRetailRoute("wechat-notify")]
    public class WeChatNotifyController : BaseController
    {
        #region Field
        //private readonly IHttpContextAccessor _accessor;
        private readonly IWeChatNotifyService _weChatNotifyService;
        private readonly ILogger _logger;
        #endregion

        #region Constructor
        public WeChatNotifyController(/*IHttpContextAccessor accessor, */IWeChatNotifyService weChatNotifyService, ILogger<WeChatNotifyController> logger)
        {
            //_accessor = accessor;
            _weChatNotifyService = weChatNotifyService;
            _logger = logger;
        }
        #endregion

        #region method

        #region 微信后台验证地址（使用Get），微信后台的“接口配置信息”的Url填写如：http://u2mttx.natappfree.cc/api/new-retail/wechat-notify/wx16dee13acf6bfff5
        /// <summary>
        /// 微信后台验证地址,需要在微信的url配置里面添加 http://u2mttx.natappfree.cc/api/new-retail/wechat-notify/wx16dee13acf6bfff5  然后Token填token，与下面方法的token变量值一致,
        /// 最后的wx16dee13acf6bfff5需要填写对应的appId
        /// 首先微信会通过此地址发送get请求执行此API，如果验证成功则会执行Post的API
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="echostr"></param>
        /// <returns></returns>
        [HttpGet("a-{appId}")]
        public Task<ActionResult> Get(PostModel postModel, string echostr)//(string signature, string timestamp, string nonce, string echostr)
        {
            var signature = postModel.Signature;
            var timestamp = postModel.Timestamp;
            var nonce = postModel.Nonce;
            var appId = postModel.AppId;
            return Task.Factory.StartNew(() =>
            {
                bool valid = _weChatNotifyService.Check(signature, timestamp, nonce, appId);
                if (!valid)
                {
                    return Content("fail");
                }

                return Content(echostr);

            }).ContinueWith<ActionResult>(task => Content(task.Result.Content.ToString()));
        }
        #endregion

        #region Post微信消息管理回复
        /// <summary>
        /// 微信消息管理回复
        /// </summary>
        /// <returns></returns>
        [HttpPost("a-{appId}")]
        public async Task Post([FromRoute(Name = "appId")] string appId)
        {
            //由于使用了中间件，因此这边为空方法
            try
            {
                #region 注释 弃用
                //using var reader = new StreamReader(Request.Body, Encoding.UTF8);
                //string content = await reader.ReadToEndAsync();
                //_logger.LogInformation("接收到微信推送的数据：{0}", content);
                //var responseMsg = _weChatNotifyService.WxResponseMessage(content, appId);
                //var context = _accessor.HttpContext;
                //context.Response.Clear();
                //context.Response.ContentType = "UTF-8";
                //await context.Response.WriteAsync(responseMsg);

                //var context = _accessor.HttpContext;
                //IDictionary<string, string> parameters = null;
                //var token = _configuration.GetSection("WeChatOptions").GetSection("WeChatBaseOptions").GetSection("token").Value;
                //try
                //{
                //context.Response.ContentType = "text/plain";
                //HttpRequest request = context.Request;
                ////验证消息真实性
                //var queryString = request.QueryString;
                //parameters = UtilsHelper.GetQueryParameters(queryString);
                //string signature = parameters["signature"].ToString();
                //string timestamp = parameters["timestamp"].ToString();
                //string nonce = parameters["nonce"].ToString();
                //if (!CheckSignature.Check(signature, timestamp, nonce, token))
                //// if (!WeChatCommon.CheckSignature(token, signature, timestamp, nonce))
                //{
                //    //("验证消息真实性---失败！");
                //    context.Response.WriteAsync(string.Empty);
                //    return;
                //}

                //string responseMsg = "hhh";// WeChatCommon.WxResponse(request);
                //context.Response.Clear();
                //context.Response.ContentType = "UTF-8";
                //await context.Response.WriteAsync(responseMsg);
                //}
                //catch (Exception e)
                //{
                //await context.Response.WriteAsync(e.Message);
                //}
                #endregion

                await Task.Run(() => { Console.WriteLine("微信消息回调成功!");/*_logger.LogInformation("微信消息回调成功！");*/ });
                //return await Task.Run(() => { return Content("success"); });
            }
            catch(Exception e)
            {
                _logger.LogError(message: e.Message, exception: e);
                throw;
            }
        }
        #endregion

        #region 微信支付回调相关

        #region 微信支付，设置消息通知地址API
        /// <summary>
        /// 微信支付，设置消息通知地址API。用于设置接收营销事件通知的URL，可接收营销相关的事件通知:核销通知
        /// </summary>
        /// <returns></returns>
        [HttpPost("wechat-updatemarketingfavorcallback")]
        public async Task<ResponseEntity<string>> UpdateMarketingFavorCallback([FromBody] MarketingFavorNotifyInputDto inputData)
        {
            var ret = new ResponseEntity<string>();
            try
            {
                var result = await _weChatNotifyService.UpdateMarketingFavorCallback();
                if (!string.IsNullOrEmpty(result.Item2))
                {
                    ret.Data = null;
                    ret.SetError("设置消息通知地址失败！" + result.Item2);
                }
                ret.SetData(result.Item1);
            }
            catch(Exception e)
            {
                ret.Data = null;
                ret.SetError("设置消息通知地址异常！" + e.Message);
                _logger.LogError(e.Message);
            }
            return ret;
        }
        #endregion

        #region 微信回调通知
        [HttpPost]
        [Route("m-{merchantId}/messagepush")]
        public async Task<IActionResult> ReceiveMessage(
            [FromRoute(Name = "merchantId")] string merchantId,
            [FromHeader(Name = "Wechatpay-Timestamp")] string timestamp,
            [FromHeader(Name = "Wechatpay-Nonce")] string nonce,
            [FromHeader(Name = "Wechatpay-Signature")] string signature,
            [FromHeader(Name = "Wechatpay-Serial")] string serialNumber)
        {
            using var reader = new StreamReader(Request.Body, Encoding.UTF8);
            string content = await reader.ReadToEndAsync();
            _logger.LogInformation("接收到微信支付推送的数据：{0}", content);

            bool valid = _weChatNotifyService.VerifyEventSignature(signature, timestamp, nonce, merchantId, serialNumber, content);
            if (!valid)
            {
                // NOTICE:
                //   需提前注入 CertificateManager、并添加平台证书，才可以使用扩展方法执行验签操作。
                //   有关 CertificateManager 的用法请参阅《开发文档 / 高级技巧 / 如何验证回调通知事件签名？》。
                //   后续如何解密并反序列化，请参阅《开发文档 / 高级技巧 / 如何解密回调通知事件中的敏感数据？》。

                return new JsonResult(new { code = "FAIL", message = "验签失败" });
            }
            else
            {
                //验签成功则需要将券的状态改成已使用
                var result = await _weChatNotifyService.WxPayNotifyResponseMessage(content, merchantId);
            }

            return new JsonResult(new { code = "SUCCESS", message = "成功" });
        }
        #endregion

        #endregion

        #endregion
    }
}
